import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import static org.junit.Assert.assertEquals;

public class CharCounterTest {
    private CharCounter counter;

    @Before
    public void setUp() {
        counter = new CharCounter();
    }

    @Test
    public void testEmptyStream() throws IOException {
        InputStream ins = new ByteArrayInputStream(new byte[0]);
        assertEquals(0, counter.countAll(ins));
    }

    @Test
    public void testBasicCounting() throws IOException {
        String test = "teststring";
        InputStream ins = new ByteArrayInputStream(test.getBytes(StandardCharsets.UTF_8));
        assertEquals(10, counter.countAll(ins));
        assertEquals(3, counter.getCount('t'));
        assertEquals(2, counter.getCount('s'));
        assertEquals(1, counter.getCount('r'));
        assertEquals(1, counter.getCount('i'));
        assertEquals(1, counter.getCount('n'));
        assertEquals(1, counter.getCount('g'));
    }

    @Test
    public void testClear() {
        counter.add('a');
        counter.add('a');
        assertEquals(2, counter.getCount('a'));
        counter.clear();
        assertEquals(0, counter.getCount('a'));
    }

    @Test
    public void testSet() {
        counter.set('b', 5);
        assertEquals(5, counter.getCount('b'));
    }

    @Test
    public void testGetTable() throws IOException {
        String test = "aaa";
        InputStream ins = new ByteArrayInputStream(test.getBytes(StandardCharsets.UTF_8));
        counter.countAll(ins);
        Map<Integer, Integer> table = counter.getTable();
        assertEquals(1, table.size());
        assertEquals(Integer.valueOf(3), table.get((int)'a'));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidCharacterGetCount() {
        counter.getCount(-1);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidCharacterAdd() {
        counter.add(-1);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidCharacterSet() {
        counter.set(-1, 5);
    }
}
